package com.wzh.yuvwater;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.wzh.yuvwater.activity.BaseActivity;
import com.wzh.yuvwater.constants.BasePermission;
import com.wzh.yuvwater.encoder.CameraWrapper;
import com.wzh.yuvwater.encoder.VideoCodecManager;
import com.wzh.yuvwater.jni.YuvOsdUtils;
import com.wzh.yuvwater.muxer.MuxerManager;
import com.wzh.yuvwater.utils.BitmapUtils;
import com.wzh.yuvwater.utils.Logger1;
import com.wzh.yuvwater.utils.MonitorUtils;

import java.util.Locale;

public class MainActivity extends BaseActivity implements View.OnClickListener {

    private static String TAG = "MainActivity";

    private View rlRoot;
    private Button mBtStart;
    private Button mBtPause;
    private ImageView imageView;
    private TextView openVideo;
    private SurfaceView surfaceView;

    private long mRecordTime;
    //专门处理计时器
    private Handler tHandler = new Handler();
    private static Context context;

    private boolean isRecord;
    private boolean isPause;
    private String saveVideoPath;
    private MuxerManager.VideoCallback videoCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = this;
        //必须在setContentView之前执行，否则会报错。
        setWindow();
        setContentView(R.layout.activity_main);
        initView();
    }

    @Override
    protected void onStop() {
        super.onStop();
        if (isRecord){
            Toast.makeText(this, "离开录像界面，暂停录制", Toast.LENGTH_SHORT).show();
            MuxerManager.getInstance().sendPauseMuxerMsg();
            isPause = true;
            mBtPause.setText("继续录制");
        }
    }

    private void initView() {
        surfaceView = findViewById(R.id.surface);
        rlRoot = findViewById(R.id.rl_root);
        imageView = findViewById(R.id.previewImage);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                //后台切换至前台也会执行此方法
                initCamera(false);
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });

        videoCallback = (nv12Data) -> runOnUiThread(() -> {
            byte[] newData = nv12Data.clone();
            //此方法实际上可以相互转换（也可以将nv12转为nv21）
            YuvOsdUtils.nv21ToNv12(nv12Data, newData, CameraWrapper.SRC_VIDEO_WIDTH, CameraWrapper.SRC_VIDEO_HEIGHT);
            Bitmap bitmap = BitmapUtils.nv12ToBitmap(newData, CameraWrapper.SRC_VIDEO_WIDTH, CameraWrapper.SRC_VIDEO_HEIGHT);
            imageView.setImageBitmap(bitmap);
        });

        openVideo = findViewById(R.id.openVideo);

        mBtStart = findViewById(R.id.bt_start);
        mBtPause = findViewById(R.id.bt_pause);
        mBtStart.setOnClickListener(this);
        findViewById(R.id.bt_stop).setOnClickListener(this);
        mBtPause.setOnClickListener(this);

        openVideo.setOnClickListener(v -> {
            Intent it = new Intent(Intent.ACTION_VIEW);
            it.setDataAndType(Uri.parse(saveVideoPath), "video/*");
            Intent intent = Intent.createChooser(it, "选择打开的应用");
            startActivity(intent);
        });
    }

    private void initCamera(boolean isPort) {
        requestPermissions(BasePermission.REQUIRED_PERMISSIONS);

        VideoCodecManager.getInstance().setVideoCallback(videoCallback);

        int cameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
        CameraWrapper.getInstance().setScreenPort(isPort);
        CameraWrapper.getInstance()
                .setCameraId(cameraId)
                .doOpenCamera(surfaceView);

        Camera.PreviewCallback previewCallback = (data, camera) -> {
            //把视频源数据加入编码中
            VideoCodecManager.getInstance().addFrameData(data);
            camera.addCallbackBuffer(data);
        };

        CameraWrapper.getInstance().setCameraPreviewCallback(previewCallback);
        CameraWrapper.getInstance().pausePreview();
        CameraWrapper.getInstance().startPreview();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_start:
                if (isRecord) {
                    return;
                }
                isRecord = true;
                isPause = false;
                mRecordTime = 0;

                initCamera(false);
                CameraWrapper.getInstance().startRecording();
                saveVideoPath = MonitorUtils.getVideoFilePath();
                MuxerManager.getInstance().sendReStartMuxerMsg(saveVideoPath);
                mBtStart.setEnabled(false);
                mBtPause.setEnabled(true);
                mBtStart.setText("00:00");
                mBtPause.setText("暂停录制");

                tHandler.removeCallbacksAndMessages(null);
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        if (!isPause) {
                            mRecordTime++;
                            mBtStart.setText(getStrRecordTime(mRecordTime));
                        }
                        tHandler.postDelayed(this, 1000);
                    }
                };
                tHandler.postDelayed(runnable, 1000);
                break;
            case R.id.bt_pause:
                if (!isPause) {
                    isPause = true;
                    MuxerManager.getInstance().sendPauseMuxerMsg();
                    mBtPause.setText("继续录制");
                } else {
                    isPause = false;
                    MuxerManager.getInstance().sendResumeMuxerMsg();
                    mBtPause.setText("暂停录制");
                }
                break;
            case R.id.bt_stop:
                Toast.makeText(this, "视频文件保存至：" + saveVideoPath, Toast.LENGTH_SHORT).show();
                MuxerManager.getInstance().sendStopMuxerMsg();
                tHandler.removeCallbacksAndMessages(null);
                openVideo.setText("保存路径：" + saveVideoPath);
                openVideo.setEnabled(true);
                mBtStart.setEnabled(true);
                mBtPause.setEnabled(false);
                mBtStart.setText("开始录制");
                mBtPause.setText("继续录制");
                isRecord = false;
                isPause = false;
                break;
            default:
                break;
        }
    }

    private void changeSurfaceView(boolean isPort) {
        int screenW = rlRoot.getMeasuredWidth();
        int screenH = rlRoot.getMeasuredHeight();
        Logger1.d("TAG", "changeSurfaceView" + screenW + "*" + screenH);
        if (isPort) {
            float scaleW = (float) screenW / CameraWrapper.SRC_VIDEO_HEIGHT;
            float scaleH = (float) screenH / CameraWrapper.SRC_VIDEO_WIDTH;
            float scale = Math.min(scaleH, scaleW);
            surfaceView.getLayoutParams().width = (int) (CameraWrapper.SRC_VIDEO_HEIGHT * scale);
            surfaceView.getLayoutParams().height = (int) (CameraWrapper.SRC_VIDEO_WIDTH * scale);
            surfaceView.requestLayout();
        } else {
            float scaleW = (float) screenW / CameraWrapper.SRC_VIDEO_WIDTH;
            float scaleH = (float) screenH / CameraWrapper.SRC_VIDEO_HEIGHT;
            float scale = Math.min(scaleH, scaleW);
            surfaceView.getLayoutParams().width = (int) (CameraWrapper.SRC_VIDEO_WIDTH * scale);
            surfaceView.getLayoutParams().height = (int) (CameraWrapper.SRC_VIDEO_HEIGHT * scale);
            surfaceView.requestLayout();
        }
    }

    private String getStrRecordTime(long mRecordTime) {
        long minute = mRecordTime / 60;
        long second = mRecordTime % 60;
        return String.format(Locale.CHINA, "%02d:%02d", minute, second);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (tHandler != null) {
            tHandler.removeCallbacksAndMessages(null);
        }
        tHandler = null;
    }

    private void setWindow() {
        // 隐藏标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        // 隐藏状态栏
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //设置屏幕常亮
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    /**
     * 检查权限
     */
    private void requestPermissions(@NonNull String... permissions) {
        //检查权限
        if (checkSelfPermissions(permissions)) {
            return;
        }
        Callback callback = new Callback() {
            @Override
            public void success() {
            }

            @Override
            public void failed() {
                Toast.makeText(context, "未授予相机、存储、录音权限！", Toast.LENGTH_SHORT).show();
            }
        };
        String permissionDes = "请给予相机、录音、存储权限，以便app正常工作";
        this.requestPermission(permissionDes, callback, permissions);
    }

}
